#include "protocol_parser.h"

#include "protocol_center.h"

ProtocolParser::ProtocolData ProtocolParser::ParserUrl(const std::string & url)
{
    ProtocolData data   = {};
    int          result = Parser(url, data);
    return result >= 0 ? data : ProtocolData{};
}

std::string ProtocolParser::GetUrl(ProtocolData & protocol_data, const std::string & uri)
{
    std::string url =
        protocol_data.m_protocol.m_protocol_name + "://" + protocol_data.m_host + ":" + std::to_string(protocol_data.m_port);
    if (uri.empty() || uri[0] != '/')
    {
        url += "/";
    }
    url += uri;
    return url;
}

int ProtocolParser::Parser(const std::string & url, ProtocolData & data)
{
    int  result = 0;
    auto index  = url.find("://");
    if (index == std::string::npos)
    {
        result = -1;
    }
    else
    {
        std::string protocol = url.substr(0, index);
        std::string host;
        std::string port;
        std::string uri;
        auto        host_index = url.find("/", index + 3);
        if (host_index == std::string::npos)
        {
            host = url.substr(index + 3);
        }
        else
        {
            host = url.substr(index + 3, host_index - index - 3);
            uri  = url.substr(host_index);
        }
        auto port_index = host.find(':');
        if (port_index != std::string::npos)
        {
            port = host.substr(port_index + 1);
            host = host.substr(0, port_index);
        }
        auto protocol_data = ProtocolCenter::FindProtocol(protocol);
        if (protocol_data.m_protocol_name.empty())
        {
            result = -1;
        }
        else
        {
            data.m_host = host;
            data.m_port = (port.empty() || (atoi(port.c_str()) == 0)) ? protocol_data.m_protocol_port : atoi(port.c_str());
            data.m_uri  = uri;
            data.m_protocol = protocol_data;
        }
    }
    return result;
}
